package com.dji.sample.wayline.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dji.sample.wayline.dao.IDockApronMapper;
import com.dji.sample.wayline.model.entity.DockApron;
import com.dji.sample.wayline.service.IDockApronService;
import com.dji.sdk.common.HttpResultResponse;
import com.dji.sdk.common.Pagination;
import com.dji.sdk.common.PaginationData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 机场停机坪服务实现类
 * 实现对机场停机坪信息进行增删改查操作的具体逻辑
 *
 * @author sean
 * @version 1.0
 * @date 2024/1/1
 */
@Service
@Transactional
@Slf4j
public class DockApronServiceImpl implements IDockApronService {

    @Autowired
    private IDockApronMapper dockApronMapper;

    @Override
    public HttpResultResponse<DockApron> createDockApron(DockApron dockApron) {
        try {
            log.info("开始创建停机坪: {}", dockApron);

            System.out.println("------------------------------------------"+dockApron);
            
            // 检查停机坪编号是否已存在
            if (StringUtils.hasText(dockApron.getApronNo())) {
                log.info("检查停机坪编号是否存在: {}", dockApron.getApronNo());
                Optional<DockApron> existingApron = getDockApronByApronNo(dockApron.getApronNo());
                if (existingApron.isPresent()) {
                    log.warn("停机坪编号已存在: {}", dockApron.getApronNo());
                    return HttpResultResponse.error("停机坪编号已存在");
                }
            }

            // 检查停机坪名称是否已存在
            if (StringUtils.hasText(dockApron.getApronName())) {
                log.info("检查停机坪名称是否存在: {}", dockApron.getApronName());
                Optional<DockApron> existingApron = getDockApronByApronName(dockApron.getApronName());
                if (existingApron.isPresent()) {
                    log.warn("停机坪名称已存在: {}", dockApron.getApronName());
                    return HttpResultResponse.error("停机坪名称已存在");
                }
            }

            // 手动设置时间戳，以防自动填充失败
            if (dockApron.getCreateTime() == null) {
                dockApron.setCreateTime(System.currentTimeMillis());
            }
            if (dockApron.getUpdateTime() == null) {
                dockApron.setUpdateTime(System.currentTimeMillis());
            }
            
            log.info("准备插入停机坪数据: {}", dockApron);
            int result = dockApronMapper.insert(dockApron);
            log.info("插入结果: {}, 停机坪ID: {}", result, dockApron.getId());
            
            if (result > 0) {
                log.info("停机坪创建成功: {}", dockApron);
                return HttpResultResponse.success(dockApron);
            } else {
                log.error("插入操作返回0，创建失败");
                return HttpResultResponse.error("创建停机坪失败");
            }
        } catch (Exception e) {
            log.error("创建停机坪异常", e);
            return HttpResultResponse.error("创建停机坪失败: " + e.getMessage());
        }
    }

    @Override
    public HttpResultResponse<Boolean> deleteDockApronById(Long id) {
        try {
            if (id == null) {
                return HttpResultResponse.error("停机坪ID不能为空");
            }

            int result = dockApronMapper.deleteById(id);
            // 如果删除的记录不存在，也应该返回成功（幂等性）
            return HttpResultResponse.success(result >= 0);
        } catch (Exception e) {
            log.error("删除停机坪失败", e);
            return HttpResultResponse.error("删除停机坪失败: " + e.getMessage());
        }
    }

    @Override
    public HttpResultResponse<Boolean> deleteDockApronByApronNo(String apronNo) {
        try {
            if (!StringUtils.hasText(apronNo)) {
                return HttpResultResponse.error("停机坪编号不能为空");
            }

            int result = dockApronMapper.delete(
                    new LambdaQueryWrapper<DockApron>()
                            .eq(DockApron::getApronNo, apronNo)
            );
            // 如果删除的记录不存在，也应该返回成功（幂等性）
            return HttpResultResponse.success(result >= 0);
        } catch (Exception e) {
            log.error("删除停机坪失败", e);
            return HttpResultResponse.error("删除停机坪失败: " + e.getMessage());
        }
    }

    @Override
    public HttpResultResponse<Boolean> deleteDockAprons(List<String> apronNos) {
        try {
            if (apronNos == null || apronNos.isEmpty()) {
                return HttpResultResponse.error("停机坪编号列表不能为空");
            }

            int result = dockApronMapper.delete(
                    new LambdaQueryWrapper<DockApron>()
                            .in(DockApron::getApronNo, apronNos)
            );
            // 修改返回逻辑：只要删除了至少一条记录就认为成功
            // 如果传入的编号中有不存在的，不应该认为是失败
            return HttpResultResponse.success(result >= 0);
        } catch (Exception e) {
            log.error("批量删除停机坪失败", e);
            return HttpResultResponse.error("批量删除停机坪失败: " + e.getMessage());
        }
    }

    @Override
    public HttpResultResponse<Boolean> updateDockApron(DockApron dockApron) {
        try {
            if (!StringUtils.hasText(dockApron.getApronNo())) {
                return HttpResultResponse.error("停机坪编号不能为空");
            }

            // 检查停机坪是否存在
            Optional<DockApron> existingApron = getDockApronByApronNo(dockApron.getApronNo());
            if (!existingApron.isPresent()) {
                return HttpResultResponse.error("停机坪不存在");
            }

            // 设置正确的ID，确保更新操作能正确执行
            dockApron.setId(existingApron.get().getId());

            // 检查停机坪名称是否与其他停机坪重复
            if (StringUtils.hasText(dockApron.getApronName())) {
                Optional<DockApron> apronByName = getDockApronByApronName(dockApron.getApronName());
                if (apronByName.isPresent() && !apronByName.get().getApronNo().equals(dockApron.getApronNo())) {
                    return HttpResultResponse.error("停机坪名称已存在");
                }
            }

            // 使用 updateById 方法，这是更标准和可靠的更新方式
            int result = dockApronMapper.updateById(dockApron);
            // 更新操作：只要没有异常就认为成功
            return HttpResultResponse.success(result >= 0);
        } catch (Exception e) {
            log.error("更新停机坪失败", e);
            return HttpResultResponse.error("更新停机坪失败: " + e.getMessage());
        }
    }

    @Override
    public Optional<DockApron> getDockApronById(Long id) {
        if (id == null) {
            return Optional.empty();
        }
        
        DockApron dockApron = dockApronMapper.selectById(id);
        return Optional.ofNullable(dockApron);
    }

    @Override
    public Optional<DockApron> getDockApronByApronNo(String apronNo) {
        if (!StringUtils.hasText(apronNo)) {
            return Optional.empty();
        }
        
        DockApron dockApron = dockApronMapper.selectOne(
                new LambdaQueryWrapper<DockApron>()
                        .eq(DockApron::getApronNo, apronNo)
        );
        return Optional.ofNullable(dockApron);
    }

    @Override
    public Optional<DockApron> getDockApronByApronName(String apronName) {
        if (!StringUtils.hasText(apronName)) {
            return Optional.empty();
        }
        
        DockApron dockApron = dockApronMapper.selectOne(
                new LambdaQueryWrapper<DockApron>()
                        .eq(DockApron::getApronName, apronName)
        );
        return Optional.ofNullable(dockApron);
    }

    @Override
    public PaginationData<DockApron> getDockAprons(long page, long pageSize, Integer status) {
        LambdaQueryWrapper<DockApron> queryWrapper = new LambdaQueryWrapper<DockApron>()
                .eq(Objects.nonNull(status), DockApron::getStatus, status)
                .orderByAsc(DockApron::getApronNo);

        Page<DockApron> pageResult = dockApronMapper.selectPage(
                new Page<>(page, pageSize), queryWrapper);

        return new PaginationData<DockApron>()
                .setList(pageResult.getRecords())
                .setPagination(new Pagination()
                        .setPage(pageResult.getCurrent())
                        .setPageSize(pageResult.getSize())
                        .setTotal(pageResult.getTotal()));
    }

    @Override
    public List<DockApron> getAllDockAprons() {
        return dockApronMapper.selectList(
                new LambdaQueryWrapper<DockApron>()
                        .orderByAsc(DockApron::getApronNo)
        );
    }

    @Override
    public List<DockApron> getDockApronsByStatus(Integer status) {
        if (status == null) {
            return getAllDockAprons();
        }
        
        return dockApronMapper.selectList(
                new LambdaQueryWrapper<DockApron>()
                        .eq(DockApron::getStatus, status)
                        .orderByAsc(DockApron::getApronNo)
        );
    }

    @Override
    public List<DockApron> getDockApronsByLocation(Double minLongitude, Double maxLongitude, 
                                                  Double minLatitude, Double maxLatitude) {
        LambdaQueryWrapper<DockApron> queryWrapper = new LambdaQueryWrapper<DockApron>()
                .ge(Objects.nonNull(minLongitude), DockApron::getLongitude, minLongitude)
                .le(Objects.nonNull(maxLongitude), DockApron::getLongitude, maxLongitude)
                .ge(Objects.nonNull(minLatitude), DockApron::getLatitude, minLatitude)
                .le(Objects.nonNull(maxLatitude), DockApron::getLatitude, maxLatitude)
                .orderByAsc(DockApron::getApronNo);

        return dockApronMapper.selectList(queryWrapper);
    }

    @Override
    public List<DockApron> getDockApronsByAltitude(Double minAltitude, Double maxAltitude) {
        LambdaQueryWrapper<DockApron> queryWrapper = new LambdaQueryWrapper<DockApron>()
                .ge(Objects.nonNull(minAltitude), DockApron::getAltitude, minAltitude)
                .le(Objects.nonNull(maxAltitude), DockApron::getAltitude, maxAltitude)
                .orderByAsc(DockApron::getApronNo);

        return dockApronMapper.selectList(queryWrapper);
    }
}